// scaup
// (c) 2010, Normen Müller, normen.mueller@gmail.com  
// $Id: Lists.scala 97 2010-08-23 09:00:50Z normen.mueller $
package scaup.data

import scaup.PimpedType

/** @thanks  Scalaz#ListsW
 *  @author  <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 *  @version 0.0.6
 */
sealed trait ListW[T] extends PimpedType[List[T]] {
  import scaup.Scaup._

  lazy val toSet = (Set[T]() /: value)(_ + _)
}

/** @thanks  Scalaz#Lists
 *  @author  <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 *  @version 0.0.6
 */
trait Lists {
  implicit def ListTo[T](as: List[T]): ListW[T] = new ListW[T] {
    val value = as
  }

  /** Provides a non-empty extractor for <code>java.util.List</code>.
   */
  private object NonEmpty {
    /** An extractor that returns a pair of the first element of a list and the remainder of the list if the list
     *  is not empty, otherwise, no match.
     */
    def unapply[T](xs: java.util.List[T]): Option[(T, java.util.List[T])] =
      if (xs isEmpty)
        None
      else Some((xs.get(0), xs.subList(1, xs.size)))
  }

  /** Provides an empty extractor for <code>java.util.List</code>.
   */
  private object Empty {
    /** An extractor that returns <code>Some</code> if the given list is empty, <code>None</code> (no match) otherwise.
     */
    def unapply[T](xs: java.util.List[T]): Option[Unit] =
      if (xs isEmpty)
        Some(())
      else None
  }

  /** Converts a <code>java.util.List</code> to a scala list.
   */
  implicit def javaList2scalaList[T](xs: java.util.List[T]): scala.List[T] = xs match {
    case NonEmpty(h, t) => h :: t
    case Empty(_) => Nil
  }

  /** Converts a scala list to a <code>java.util.List</code>.
   */
  implicit def scalaList2javaList[T](xs: scala.List[T]): java.util.List[T] = {
    val l = new java.util.LinkedList[T]
    xs foreach (l.add(_))
    l
  }

  def nil[T]: List[T] = Nil
}
